In this tutorial you create a widget store where you can browse and select widgets in one view and select widgets to see their descriptions in another view. When running the project at the end of the previous step you saw only the application background. However, the kzb binary file you created from the Kanzi Studio project and loaded in code, includes all the objects you need to create the application logic in code:
To access content from the Kanzi Studio project using code:
#include <application/kza_application_interface.h> #include <application/kza_application.h> #include <user/animation/kzu_animation_item.h> #include <user/animation/kzu_animation_clip.h> #include <user/animation/kzu_animation_player.h> #include <user/layers/kzu_viewport_layer.h> #include <user/properties/kzu_fixed_properties.h> #include <user/properties/kzu_property_registry.h> #include <user/properties/kzu_property_manager.h> #include <user/resource/kzu_image_texture.h> #include <user/resource/kzu_resource_manager.h> #include <user/scene_graph/kzu_camera.h> #include <user/scene_graph/kzu_object.h> #include <user/scene_graph/kzu_object_resources.h> #include <user/scene_graph/kzu_scene.h> #include <user/scene_graph/kzu_transformed_scene.h> #include <user/scene_graph/kzu_transformed_object.h> #include <user/ui/kzu_ui_domain.h> #include <user/ui/components/kzu_ui_grid_layout.h> #include <user/ui/components/kzu_ui_list_box.h> #include <user/ui/input_manager/kzu_click_manipulator.h> #include <user/ui/kzu_ui_component.h> #include <user/ui/message/kzu_general_messages.h> #include <user/ui/message/kzu_message.h> #include <user/ui/message/kzu_message_dispatcher.h> #include <user/ui/templates/kzu_prefab.h> #include <user/ui/kzu_screen.h> #include <core/memory/kzc_memory_manager.h>
ApplicationData structure of the Kanzi application framework. This code contains all application data containers used in this tutorial.
/* Application data container for storing references to objects. */
struct ApplicationData
{
struct KzuPrefabTemplate* widgetItemPrefabTemplate;
struct KzuPropertyType* widgetDescriptionPropertyType;
struct KzuObjectNode* widgetDescriptionLayerNode;
struct KzuObjectNode* widgetDescriptionTextBlockNode;
struct KzuObjectNode* widgetGridListboxNode;
struct KzuObjectNode* cameraObjectNode;
struct KzuObjectNode* animationTargetObjectNode;
struct KzuObjectNode* backButton;
struct KzuObjectNode* currentlySelectedObject;
struct KzuAnimationItem* targetAnimationClip;
struct KzuAnimationItem* highlightAnimationClip;
struct KzcMatrix4x4 cameraTransformationTarget;
};KzaApplicationProperties.onProjectLoaded callback implementation, allocate the memory for the structure, and store it to the application.KZS_SUCCESS. Intercept this result after every function call and forward it with kzsErrorForward.
KZ_CALLBACK kzsError projectLoaded(struct KzaApplication* application)
{
kzsError result;
struct KzcMemoryManager* memoryManager;
struct ApplicationData* applicationData;
/* Get the memory manager that is used to create objects. */
memoryManager = kzaApplicationGetApplicationMemoryManager(application);
/* Create the application data. */
result = kzcMemoryAllocVariable(memoryManager, applicationData, "Application data");
kzsErrorForward(result);
/* Set application data as user data. */
kzaApplicationSetUserData(application, applicationData);
...
kzsSuccess();
}KzaApplicationProperties.onShutdown callback implementation. For example, the application data is used for the entire application lifetime, so you have to free the memory at the KzaApplicationProperties.onShutdown callback implementation.
KZ_CALLBACK kzsError shutdown(struct KzaApplication* application)
{
kzsError result;
struct ApplicationData* applicationData;
/* Retrieve application data. */
applicationData = (struct ApplicationData*)kzaApplicationGetUserData(application);
/* Free application data. */
result = kzcMemoryFreeVariable(applicationData);
kzsErrorForward(result);
kzsSuccess();
}
KzaApplicationProperties.onProjectLoaded callback implementation.
KZ_CALLBACK kzsError projectLoaded(struct KzaApplication* application)
{
kzsError result;
...
struct KzuUIDomain* uiDomain = kzaApplicationGetUIDomain(application);
struct KzuObjectNode* screenNode
= kzuScreenToObjectNode(kzaApplicationGetScreen(application));
...
/* Load references to all required components to application data. */
{
/* Get the reference to the reusable prefab (template) for the widget icons. */
struct KzuResourceManager* resourceManager
= kzuUIDomainGetResourceManager(uiDomain);
struct KzuResource* resource;
result = kzuResourceManagerAcquireResource(resourceManager,
"kzb://Programmer_tutorial/Prefabs/Widget Item Prefab",
&resource);
kzsErrorForward(result);
applicationData->appPrefabTemplate
= kzuPrefabTemplateFromResource(resource);
/* Get the reference to the grid list box component that contains all widget instances. */
/* The path is defined by an alias you can create and edit in the Kanzi Studio project. */
applicationData->widgetGridListboxNode = kzuObjectNodeGetRelative(screenNode, "#Widget list");
}
...
kzsSuccess();
}kzuResourceManagerAcquireResource(), which returns an existing resource reference, or creates a new one and loads it. Call kzuResourceRelease to tell the resource manager that a resource handle is no longer used. Make sure that you pair each acquire call with a matching release call as in this code.
KZ_CALLBACK kzsError shutdown(struct KzaApplication* application)
{
...
/* Retrieve application data. */
struct ApplicationData* applicationData
= (struct ApplicationData*)kzaApplicationGetUserData(application);
kzsAssert(kzcIsValidPointer(applicationData));
result = kzuResourceRelease(kzuPrefabTemplateToResource(applicationData->widgetItemPrefabTemplate));
kzsErrorForward(result);
...
}